export enum MaskPlusType {
    /**
     * !#en Rect mask.
     * !#zh 使用矩形作为遮罩
     * @property {Number} RECT
     */
    RECT = 0,
    /**
     * !#en Ellipse Mask.
     * !#zh 使用椭圆作为遮罩
     * @property {Number} ELLIPSE
     */
    ELLIPSE = 1,
    /**
     * !#en Image Stencil Mask.
     * !#zh 使用图像模版作为遮罩
     * @property {Number} IMAGE_STENCIL
     */
    IMAGE_STENCIL = 2,

    /**
     * 多边形遮罩
     */
    Polygon = 3,
}

let _vec2_temp = new cc.Vec2();
let _mat4_temp = new cc.Mat4();

let _circlepoints = [];
function _calculateCircle(center, radius, segements) {
    _circlepoints.length = 0;
    let anglePerStep = Math.PI * 2 / segements;
    for (let step = 0; step < segements; ++step) {
        _circlepoints.push(cc.v2(radius.x * Math.cos(anglePerStep * step) + center.x,
            radius.y * Math.sin(anglePerStep * step) + center.y));
    }

    return _circlepoints;
}

class EllipseConfig {
    center: cc.Vec2;
    r: cc.Vec2;
    segments: number;
}

/**
 * 遮罩扩展
 * 自定义多边形遮罩
 */
const { ccclass, property, executeInEditMode, menu, help, inspector } = cc._decorator;
@ccclass
@menu('i18n:MAIN_MENU.component.renderers/MaskPlus')
@executeInEditMode
@help('i18n:COMPONENT.help_url.mask')
@inspector('packages://maskplus/inspector.js')
export default class MaskPlusRed extends cc.Mask {

    static Type = MaskPlusType;

    @property({ type: cc.Enum(MaskPlusType), override: true })
    _type: MaskPlusType = 0;
    @property({ type: cc.Enum(MaskPlusType), override: true })
    // @ts-ignore
    get type() {
        return this._type;
    }
    // @ts-ignore
    set type(value) {
        if (this._type !== value) {
            this['_resetAssembler']();
        }

        this._type = value;

        if (this._type === MaskPlusType.Polygon) {
            if (this._polygon.length === 0) {
                let [x, y, width, height] = this.getNodeRect();
                this._polygon.push(cc.v2(x, y), cc.v2(x + width, y), cc.v2(x + width, y + height), cc.v2(x, y + height));
            }
        }

        if (this._type !== MaskPlusType.IMAGE_STENCIL) {
            this.spriteFrame = null;
            this.alphaThreshold = 0;
            this._updateGraphics();
        }
        this['_activateMaterial']();
    }

    @property({ type: [cc.Vec2], serializable: true })
    _polygon: cc.Vec2[] = [];
    @property({ type: [cc.Vec2], serializable: true })
    public get polygon() {
        return this._polygon;
    }
    public set polygon(points: cc.Vec2[]) {
        this._polygon = points;
        this._updateGraphics();
    }

    private ellipse: EllipseConfig = new EllipseConfig();
    public setEllipse(center?: cc.Vec2, r?: cc.Vec2, segments?: number) {
        this.ellipse.center = center;
        this.ellipse.r = r;
        this.ellipse.segments = segments || this.segements;
    }

    _updateGraphics() {
        let node = this.node;
        let graphics = this['_graphics'];
        // Share render data with graphics content
        graphics.clear(false);
        let [x, y, width, height] = this.getNodeRect();
        if (this['_type'] === MaskPlusType.RECT) {
            graphics.rect(x, y, width, height);
        }
        else if (this['_type'] === MaskPlusType.ELLIPSE) {
            let center = this.ellipse.center || cc.v2(x + width / 2, y + height / 2);
            let radius = this.ellipse.r || { x: width / 2, y: height / 2 };
            let segments = this.ellipse.segments || this['_segments'];
            let points = _calculateCircle(center, radius, segments);
            for (let i = 0; i < points.length; ++i) {
                let point = points[i];
                if (i === 0) {
                    graphics.moveTo(point.x, point.y);
                }
                else {
                    graphics.lineTo(point.x, point.y);
                }
            }
            graphics.close();
        } else if (this['_type'] === MaskPlusType.Polygon) {
            this.initData();
            // if (this._polygon.length === 0) this._polygon.push(cc.v2(0, 0));
            // graphics.moveTo(this._polygon[0].x, this._polygon[0].y);
            // for (let i = 1; i < this._polygon.length; i++) {
            //     graphics.lineTo(this._polygon[i].x, this._polygon[i].y);
            // }
            // graphics.lineTo(this._polygon[0].x, this._polygon[0].y);
        }
        if (cc.game.renderType === cc.game.RENDER_TYPE_CANVAS) {
            graphics.stroke();
        }
        else {
            graphics.fill();
        }
    }

    private getNodeRect() {
        let width = this.node['_contentSize'].width;
        let height = this.node['_contentSize'].height;
        let x = -width * this.node['_anchorPoint'].x;
        let y = -height * this.node['_anchorPoint'].y;
        return [x, y, width, height];
    }

    /**
    * @description: 初始化数据
    */
    private initData(): void {
        // 获取关卡
        let level: number = null;
        let progressLevel = cc.sys.localStorage.getItem('progressLevel');
        if (progressLevel) {
            level = parseInt(progressLevel);
        }
        // 金字塔分配
        let kaneta: number = 550 / 11;
        // 每次增加后的值
        let addValue: number = 0;
        // 信息展示
        if (level) {
            // 超越用户百分比
            if (level === 1) {
                addValue = kaneta;
            } else if (level === 2) {
                addValue = 2 * kaneta;
            } else if (level === 3) {
                addValue = 3 * kaneta;
            } else if (level === 4) {
                addValue = 4 * kaneta;
            } else if (5 <= level && level <= 9) {
                addValue = 5 * kaneta;
            } else if (10 <= level && level <= 11) {
                addValue = 6 * kaneta;
            } else if (level === 12) {
                addValue = 7 * kaneta;
            } else if (level === 13) {
                addValue = 8 * kaneta;
            } else if (14 <= level && level <= 16) {
                addValue = 9 * kaneta;
            } else if (17 <= level && level <= 18) {
                addValue = 10 * kaneta;
            } else if (19 <= level && level <= 20) {
                addValue = 11 * kaneta;
            }
        }
        let graphics = this['_graphics'];
        if (this['_type'] === MaskPlusType.Polygon) {
            if (this._polygon.length === 0) this._polygon.push(cc.v2(0, 0));
            graphics.moveTo(this._polygon[0].x, this._polygon[0].y = addValue);
            for (let i = 1; i < this._polygon.length; i++) {
                if (i === this._polygon.length - 1) {
                    graphics.lineTo(this._polygon[i].x, this._polygon[i].y = addValue);
                } else {
                    graphics.lineTo(this._polygon[i].x, this._polygon[i].y);
                }
            }
            graphics.lineTo(this._polygon[0].x, this._polygon[0].y = addValue);
        }
    }
}
cc['MaskPlus'] = MaskPlusRed;